package org.leeloo.internal.core;

import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.actions.ActionDelegate;
import org.leeloo.core.LeelooPlugin;
import org.leeloo.core.TagService;

/**
 * Abstract class that contains common needs of translating the selected
 * variable to something of use.
 * 
 * @author Brad Reynolds
 */
public abstract class AbstractVariablesViewActionDelegate extends ActionDelegate implements IViewActionDelegate {
    /**
     * @param viewPart
     * @return current stack frame, <code>null</code> if none
     */
    protected IJavaStackFrame getStackFrame(IViewPart viewPart) {
        ISelection selection = viewPart.getViewSite()
                .getWorkbenchWindow()
                .getActivePage()
                .getSelection(IDebugUIConstants.ID_DEBUG_VIEW);

        return (IJavaStackFrame) Viewers.getSingleSelectedObject(selection, IJavaStackFrame.class);
    }

    /**
     * @category testability
     * @return tag service
     */
    protected TagService getTagService() {
        return LeelooPlugin.getDefault().getTagService();
    }

    /**
     * @param selection
     * @return java object if selection contains one, <code>null</code> if not
     *         a java object
     */
    protected IJavaObject getJavaObject(ISelection selection) {
        IJavaObject result = null;
        IJavaVariable variable = (IJavaVariable) Viewers.getSingleSelectedObject(selection, IJavaVariable.class);

        try {
            if (variable != null) {
                IJavaValue value = (IJavaValue) variable.getValue();
                if (!value.equals(((IJavaDebugTarget) variable.getDebugTarget()).nullValue())
                        && value instanceof IJavaObject) {
                    result = (IJavaObject) value;
                }
            }
        } catch (DebugException e) {
            throw new RuntimeException(e);
        }

        return result;
    }
}
